package com.itlong.cloud.utils.encrypt;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.itlong.cloud.utils.node.JsonUtil;
import org.apache.commons.lang.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 国密算法
 * 接口适配
 */
public class SMEncryptUtil {
    /**
     * <desc>
     * sdkV3版本验签方法
     * SM3
     * </desc>
     *
     * @param params
     * @param appSign
     * @param appsecret
     * @return
     */
    public static boolean checkSDKV3Sign(Map<String, Object> params, String appsecret, String appSign, String... values) {
        String result = getSDKV3Sign(params, appsecret, values);
        if (StringUtils.isEmpty(result)) {
            return false;
        }
        return result.equals(appSign);
    }

    /**
     * <desc>
     * sdkv3计算sign
     * SM3
     * </desc>
     *
     * @param params
     * @param values
     * @return
     */
    public static String getSDKV3Sign(Map<String, Object> params, String appsecret, String... values) {
        if (params == null || StringUtils.isBlank(appsecret)) {
            return null;
        }
        StringBuffer stringA = new StringBuffer();
        List<Map.Entry<String, Object>> mappingList = new ArrayList<Map.Entry<String, Object>>(params.entrySet());
        Collections.sort(mappingList, new Comparator<Map.Entry<String, Object>>() {
            @Override
            public int compare(Map.Entry<String, Object> mappingF, Map.Entry<String, Object> mappingS) {
                return mappingF.getKey().toLowerCase().compareTo(mappingS.getKey().toLowerCase());
            }
        });
        for (Map.Entry<String, Object> mapping : mappingList) {
            stringA.append(mapping.getValue() == null ? "" : mapping.getValue());
        }
        for (String value : values) {
            stringA.append(value);
        }
        stringA.append(appsecret);
        return SmUtil.sm3(stringA.toString());
    }


    /**
     * <desc>
     * SM4解密
     * </desc>
     *
     * @param sSrc
     * @param sKey
     * @return
     * @throws Exception
     */
    public static String decryptStr(String sSrc, String sKey) {
        SymmetricCrypto sm4 = new SM4(Mode.ECB, Padding.ZeroPadding,sKey.getBytes(StandardCharsets.UTF_8));
        try {
            return sm4.decryptStr(sSrc, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }

    /**
     * <desc>
     * SM4加密
     * </desc>
     *
     * @param sSrc
     * @param sKey
     * @return
     * @throws Exception
     */
    public static String encryptHex(String sSrc, String sKey) {
        SymmetricCrypto sm4 = new SM4(Mode.ECB, Padding.ZeroPadding,sKey.getBytes(StandardCharsets.UTF_8));
        try {
            return sm4.encryptHex(sSrc, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }

    /**
     * <desc>
     * 返回加密内容sdkV3
     * </desc>
     *
     * @param appsecret 开发者用户密码
     * @return
     * @author Qiang.S
     * @createDate 2018/12/27
     */
    public static Map<String, Object> getEncryptResultSDKV3(Object result, String appsecret) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            String encryptResult;
            encryptResult = encryptHex(JsonUtil.toJSON(result), appsecret);
            resultMap.put("encryptScript", encryptResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }

//    public static void main(String[] args) {
//        System.out.println(decryptStr("58ae856774c9847f9d708071274969881", "1C7E265642384731"));
//        System.out.println(encryptHex("adasd", "1C7E265642384731"));
//    }
}
